﻿#region Using

using System;
using System.Collections.Generic;
using System.Threading.Tasks;

using Common.Enums;

using GameCommon.Base;

using Menu.Components;

using Microsoft.Xna.Framework;

using GameComponent = GameCommon.Components.GameComponent;

#endregion

namespace Menu.Screens.ConnectionScreen
{
    public class ConnectionScreen : ScreenBase
    {
        private Text connectingText;

        private PlayerFinder finder;

        private double elapsedTime;

        public ConnectionScreen(IScreenChanger changer, object argument)
            : base(changer, argument)
        {
        }

        public override ScreenEnum Screen
        {
            get
            {
                return ScreenEnum.ConnectionScreen;
            }
        }

        public override void LoadContent()
        {
            this.Components = MenuLoader.Get(this.Screen);

            this.connectingText = (Text)this.Components["T_Connecting"];
            this.Animations.Add(new ConnectingTextAnimation(this.connectingText));
            this.AddCommand("Back", this.OnBack);

            this.SetupPlayerFinder();
        }

        private void SetupPlayerFinder()
        {
            this.finder = new PlayerFinder("Player " + new Random().Next());
            this.finder.Start();
        }

        public override void Update(GameTime gameTime)
        {
            base.Update(gameTime);

            this.UpdatePlayerFinder(gameTime);
        }

        private void UpdatePlayerFinder(GameTime gameTime)
        {
            if (!this.finder.OpponentFound && !this.finder.ConnectionFailed)
            {
                this.EvaluatePlayerFinder();
                return;
            }
            
            //// If player found or ConnectionFailed, switch to other screen after 1sec wait
            this.elapsedTime += gameTime.ElapsedGameTime.Milliseconds;

            if (this.elapsedTime > 1000)
            {
                if (this.finder.OpponentFound)
                {
                    this.RemoveAnyScreen();
                    this.AddScreen(ScreenEnum.Countdown, ScreenEnum.GameBoard);
                }
                else
                {
                    this.OnBack(null);
                }
            }
        }

        private void EvaluatePlayerFinder()
        {
            if (this.finder == null)
            {
                return;
            }

            switch (this.finder.EvaluateConnection())
            {
                case PlayerFinderStateEnum.Connecting:
                    break;
                case PlayerFinderStateEnum.Failure:
                    this.connectingText.Value = "Connection Failed";
                    this.connectingText.Settle();
                    this.Animations.RemoveAll(x => x is ConnectingTextAnimation);
                    break;
                case PlayerFinderStateEnum.OpponentFound:
                    this.connectingText.Value = "Opponent Found";
                    this.connectingText.Settle();
                    this.Animations.RemoveAll(x => x is ConnectingTextAnimation);
                    break;
                case PlayerFinderStateEnum.WaitingForOpponent:
                    this.connectingText.Value = "Waiting for Player";
                    this.connectingText.Settle();
                    break;
            }
        }

        private void OnBack(GameComponent sender)
        {
            this.finder.CloseConnection();

            this.RemoveScreen(this.Screen);
            this.AddScreen(ScreenEnum.MainMenu);
        }
    }
}